const misc = cc.misc;
const MaskType = cc.Mask.Type;

cc.Class({
    extends: cc.Mask,

    editor: CC_EDITOR && {
        disallowMultiple: true,
        executeInEditMode: true
    },

    properties: {
        /**************************************以下为重写**************************************/
        /**
         * !#en The mask type.
         * !#zh 遮罩类型
         * @property type
         * @type {Mask.Type}
         * @example
         * mask.type = cc.Mask.Type.RECT;
         */
        type: {
            get: function () {
                return this._type;
            },
            set: function (value) {
                if (this._type !== value) {
                    this._resetAssembler();
                }

                this._type = value;
                if (this._type !== MaskType.IMAGE_STENCIL) {
                    this.spriteFrame = null;
                    this.alphaThreshold = 0;
                    this._updateGraphics();
                }
                
                this._activateMaterial();
            },
            type: MaskType,
            tooltip: CC_DEV && 'i18n:COMPONENT.mask.type',
            override: true,
            visible: false
        },

        /**
         * !#en The mask image
         * !#zh 遮罩所需要的贴图
         * @property spriteFrame
         * @type {SpriteFrame}
         * @default null
         * @example
         * mask.spriteFrame = newSpriteFrame;
         */
        spriteFrame: {
            type: cc.SpriteFrame,
            tooltip: CC_DEV && 'i18n:COMPONENT.mask.spriteFrame',
            get: function () {
                return this._spriteFrame;
            },
            set: function (value) {
                let lastSprite = this._spriteFrame;
                if (CC_EDITOR) {
                    if ((lastSprite && lastSprite._uuid) === (value && value._uuid)) {
                        return;
                    }
                }
                else {
                    if (lastSprite === value) {
                        return;
                    }
                }
                this._spriteFrame = value;
                
                this.setVertsDirty();
                this._updateMaterial();
            },
            override: true,
            visible: false
        },

        /**
         * !#en
         * The alpha threshold.(Not supported Canvas Mode) <br/>
         * The content is drawn only where the stencil have pixel with alpha greater than the alphaThreshold. <br/>
         * Should be a float between 0 and 1. <br/>
         * This default to 0 (so alpha test is disabled).
         * When it's set to 1, the stencil will discard all pixels, nothing will be shown,
         * In previous version, it act as if the alpha test is disabled, which is incorrect.
         * !#zh
         * Alpha 阈值（不支持 Canvas 模式）<br/>
         * 只有当模板的像素的 alpha 大于 alphaThreshold 时，才会绘制内容。<br/>
         * 该数值 0 ~ 1 之间的浮点数，默认值为 0（因此禁用 alpha 测试）
         * 当被设置为 1 时，会丢弃所有蒙版像素，所以不会显示任何内容，在之前的版本中，设置为 1 等同于 0，这种效果其实是不正确的
         * @property alphaThreshold
         * @type {Number}
         * @default 0
         */
        alphaThreshold: {
            default: 0,
            type: cc.Float,
            range: [0, 1, 0.1],
            slide: true,
            tooltip: CC_DEV && 'i18n:COMPONENT.mask.alphaThreshold',
            notify: function () {
                if (cc.game.renderType === cc.game.RENDER_TYPE_CANVAS) {
                    cc.warnID(4201);
                    return;
                }
                this._updateMaterial();
            },
            override: true,
            visible: false
        },

        /**
         * TODO: remove segments, not supported by graphics
         * !#en The segements for ellipse mask.
         * !#zh 椭圆遮罩的曲线细分数
         * @property segements
         * @type {Number}
         * @default 64
         */
        segements: {
            get: function () {
                return this._segments;
            },
            set: function (value) {
                this._segments = misc.clampf(value, SEGEMENTS_MIN, SEGEMENTS_MAX);
                this._updateGraphics();
            },
            type: cc.Integer,
            tooltip: CC_DEV && 'i18n:COMPONENT.mask.segements',
            override: true,
            visible: false
        },

        /**
         * !#en The materials used by this render component.
         * !#zh 渲染组件使用的材质。
         * @property {[Material]} sharedMaterials
         */
        materials: {
            get () {
                return this._materials;
            },
            set (val) {
                this._materials = val;
                this._activateMaterial();
            },
            type: [cc.Material],
            displayName: 'Materials',
            animatable: false,
            override: true,
            visible: false
        },

        invertTouch: {
            default: true,
            tooltip: 'inverted属性是否影响touch',
            visible() {
                return this.inverted;
            }
        }
    },

    ctor() {
        // this.constructor._assembler = cc.Mask._assembler;
        // this.constructor._postAssembler = cc.Mask._postAssembler;

        // this._assembler = this.constructor._assembler;
        // this._postAssembler = this.constructor._postAssembler;
    },

    onLoad() {
        const graphics = this.getComponent('baseColorShap');
        if (!graphics) return;
        graphics._graphics && graphics._graphics.node.destroy();
        graphics._graphics = this._graphics;
        graphics.updateColorShap();
    },

    onDestroy() {
        this._super && this._super();
        const graphics = this.getComponent('baseColorShap');
        graphics && (graphics._graphics = null);
    },

    _updateGraphics() {
        const graphics = this.getComponent('baseColorShap');
        graphics.updateColorShap();
    },

    _hitTest(cameraPt) {
        let result = this._super(cameraPt);
        if (this.inverted && !this.invertTouch) {
            result = !result;
        }
        return result;
    }
});